package com.itheima.tliasmanagement.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.tliasmanagement.dto.*;
import com.itheima.tliasmanagement.entity.Emp;
import com.itheima.tliasmanagement.entity.EmpExpr;
import com.itheima.tliasmanagement.entity.EmpLog;
import com.itheima.tliasmanagement.exception.BizException;
import com.itheima.tliasmanagement.mapper.EmpExprMapper;
import com.itheima.tliasmanagement.mapper.EmpMapper;
import com.itheima.tliasmanagement.service.EmpLogService;
import com.itheima.tliasmanagement.service.EmpService;
import com.itheima.tliasmanagement.util.Constant;
import com.itheima.tliasmanagement.util.JwtUtils;
import com.itheima.tliasmanagement.vo.EmpListVo;
import com.itheima.tliasmanagement.vo.EmpVo;
import com.itheima.tliasmanagement.vo.LoginResultVo;
import com.itheima.tliasmanagement.vo.PageBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprMapper exprMapper;

    @Autowired
    private EmpLogService logService;



    @Override
    public PageBean<EmpListVo> emps(EmpListDTO dto) {
        // 1.开启分页
        PageHelper.startPage(dto.getPage(), dto.getPageSize());
        // 2. 当前页的列表查询
        Page<EmpListVo> page = empMapper.page(dto);
        //3. 组合，封装返回
        return new PageBean(page.getTotal(), page.getResult());
    }

    public PageBean<EmpListVo> emps1(EmpListDTO dto) {
        // 1. 查总条数
        int count = empMapper.totalCount();
        // 2. 查当前页的列表  select * from emp limit (page-1)*pageSize,pageSize
        int start = (dto.getPage()-1)*dto.getPageSize();
        List<EmpListVo> rows = empMapper.selectPage(start, dto.getPageSize());
        // 3. 组合，封装返回
        return new PageBean(Long.valueOf(count), rows);
    }

    @Override
    //@Transactional(rollbackFor = Exception.class) //AOP
    public void addEmp(AddEmpDto dto) {
        boolean success =false;
        // 判断用户名是否重复
        Emp empDB = empMapper.selectByUsername(dto.getUsername());
        if(empDB != null){
            // 说明 用户名重复
            throw new BizException("用户名重复");
        }
        // 判断手机号是否重复
        empDB = empMapper.selectByPhone(dto.getPhone());
        if(empDB != null){
            // 说明 手机号是否重复
            throw new BizException("手机号重复");
        }
        // 开启事务
        try {
            //业务逻辑
            // 1. 添加员工信息
            // 创建emp的实体对象
            Emp emp = new Emp();
            // 拷贝参数到实体
            BeanUtils.copyProperties(dto, emp);
            // 补充字段 password、create_time update_time
            emp.setPassword("123456");
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            // insert到emp表
            empMapper.insert(emp);
            // System.out.println(1/0);
            //2. 添加工作经历
            // 前端传递的参数
            List<AddEmpExprDto> exprDtoList = dto.getExprList();
            // 只有 当有工作经历的时候才需要保存
            if (!CollectionUtils.isEmpty(exprDtoList)) {
                // 数据的实体对象
                List<EmpExpr> exprList = new ArrayList<>();
                // 把前端传递的参数转化成数据库的实体对象
                for (AddEmpExprDto exprDto : exprDtoList) {
                    EmpExpr expr = new EmpExpr();
                    BeanUtils.copyProperties(exprDto, expr);
                    // 把保存到数据库以后的emp的id设置到empId字段，建立emp和emp_expr的关联关系
                    expr.setEmpId(emp.getId());
                    exprList.add(expr);
                }
                // insert到emp_expr表
                exprMapper.insertBatch(exprList);
            }
            success = true;
            // 提交事务
        }catch(Exception e){
            log.error(e.getMessage(), e);
            success = false;
            throw new RuntimeException();
            //回滚事务
        }finally {
            // 记录日志
            EmpLog empLog = new EmpLog();
            empLog.setOperateTime(LocalDateTime.now());
            empLog.setInfo("添加员工"+(success?"成功":"失败"));
            logService.insertLog(empLog);
        }
    }

    //事务控制
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteEmps(List<Integer> ids) {
        // 删除emp
        empMapper.deleteByIds(ids);
        // 删除emp_expr
        exprMapper.deleteByEmpIds(ids);
    }

    @Override
    public EmpVo getById(Integer id) {
//        // 查询emp
//        Emp emp = empMapper.selectById(id);
//        // 查询expr
//        List<EmpExpr> exprList = exprMapper.selectByEmpId(id);
//        // 组装返回
//        EmpVo vo = new EmpVo();
//        BeanUtils.copyProperties(emp, vo);
//        vo.setExprList(exprList);
        EmpVo vo = empMapper.selectByIdWithExprList(id);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmp(UpdateEmpDto dto) {
        // 更新update emp
        Emp emp = new Emp();
        BeanUtils.copyProperties(dto, emp);
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.update(emp);
        // 删除旧的工作经历 delete
        Integer empId = dto.getId();
        List<Integer> empIds = Arrays.asList(empId);
        exprMapper.deleteByEmpIds(empIds);
        // insert 新的工作经历
        List<AddEmpExprDto> exprDtoList = dto.getExprList();
        if(!CollectionUtils.isEmpty(exprDtoList)){
            // 把dto的list转化成了expr的list
            List<EmpExpr> exprList = new ArrayList<>();
            for (AddEmpExprDto addEmpExprDto : exprDtoList) {
                EmpExpr expr = new EmpExpr();
                BeanUtils.copyProperties(addEmpExprDto, expr);
                // 重新给expr的员工id赋值，建立关联关系
                expr.setEmpId(empId);
                exprList.add(expr);
            }
//            List<EmpExpr> exprList = exprDtoList.stream().map(exprDto -> {
//                EmpExpr expr = new EmpExpr();
//                BeanUtils.copyProperties(exprDto, expr);
//                return expr;
//            }).collect(Collectors.toList());
            exprMapper.insertBatch(exprList);
        }
    }

    @Override
    public List<Emp> all() {
        return empMapper.all();
    }

    @Override
    public LoginResultVo login(LoginDto dto) {
        // 根据用户名查数据库
        Emp emp = empMapper.selectByUsername(dto.getUsername());
        // 查不到，返回
        if(emp == null){
            throw new BizException("用户不存在");
        }
        // 查到了，比对密码
        String passwordDB = emp.getPassword();
        String passwordInput = dto.getPassword();
        if(!Objects.equals(passwordDB, passwordInput)){
            // 密码不匹配， 返回
            throw new BizException("密码错误");
        }
        //登陆时成功的，生成jwt 的 token
        Map<String, Object> claim = new HashMap<>();
        claim.put(Constant.ID, emp.getId());
        claim.put(Constant.USERNAME, emp.getUsername());
        claim.put("name", emp.getName());
        String token = JwtUtils.generateJwt(claim);
        return new LoginResultVo(emp.getId(), emp.getUsername(), emp.getName(), token);
    }
}
